/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package Intelligence;

import java.util.LinkedList;
import model.Board;
import model.Player;
import util.Difficulty;
import util.FileReaderUtil;
import util.Movement;

/**
 *
 * @author JE
 */
public class AIPlayer extends Player {

    private Difficulty difficulty;
    public static final int INSANE=15;
    public static final int HARD=8;
    public static final int MEDIUM=5;
    public static final int EASY=3;
    
    private boolean color;
    
    private Movement nextMove;
    private int lastAlphaBetaValue;
    
    public AIPlayer(Difficulty difficulty, boolean color){
        setDifficulty(difficulty);
        this.color = color;
    }
    public AIPlayer(){
        this(Difficulty.MEDIUM,Player.RED);
    }
    public Difficulty getDifficulty(){
        return difficulty;
    }

    private int maxValue(Board bd, int alpha, int beta, int depth) {
        int currentMax = Integer.MIN_VALUE;
        if (depth == 0) {
            return bd.getHeuristic(color);
        } else {
            LinkedList<Board> listBds = createListOfBoardsWithPossibleMoves(bd, color);
            for (int i = 0; i < listBds.size(); i++) {
                Board successor = listBds.get(i);
                int minimumValueOfSuccessor = minValue(successor, alpha, beta, depth - 1);
                if (minimumValueOfSuccessor > currentMax) {
                    currentMax = minimumValueOfSuccessor;
                    bd.setNextMove(successor.getLastMove());
                }
                if (currentMax >= beta) {
                    //System.out.println("pruning from max");
                    return currentMax;
                }
                alpha = Math.max(alpha, currentMax);
            }
            return currentMax;
        }

    }

    private int minValue(Board bd, int alpha, int beta, int depth) {
        int currentMin = Integer.MAX_VALUE;

        if (depth == 0) {
            return bd.getHeuristic(color);

        } else {
            LinkedList<Board> listBds = createListOfBoardsWithPossibleMoves(bd, !color);
            for (int i = 0; i < listBds.size(); i++) {
                Board successor = listBds.get(i);
                int maximumValueOfSuccessor = maxValue(successor, alpha, beta, depth - 1);
                if (maximumValueOfSuccessor < currentMin) {
                    currentMin = maximumValueOfSuccessor;
                    bd.setNextMove(successor.getLastMove());
                }
                if (currentMin <= alpha) {
                    //System.out.println("pruning from min");
                    return currentMin;
                }
                beta = Math.min(beta, currentMin);

            }
            return currentMin;
        }

    }

    public void getAlphaBetaValue(Board presentBd) {
        int oldLABV = lastAlphaBetaValue;
         lastAlphaBetaValue=maxValue(presentBd, Integer.MIN_VALUE, Integer.MAX_VALUE, difficulty.getLevel());
         firePropertyChange("lastAlphaBetaValue", oldLABV, lastAlphaBetaValue);

    }
    public Movement getNextMove(Board board){
        getAlphaBetaValue(board);
        Movement oldNextMove = nextMove;
        nextMove = board.getNextMove();
        firePropertyChange("lastMove", oldNextMove, nextMove);
        return nextMove;
    }
    public void setDifficulty(Difficulty difficulty){
        firePropertyChange("difficulty", this.difficulty, difficulty);
        this.difficulty=difficulty;
    }
    

    public static void main(String[] args) {
        Board bd = new Board(FileReaderUtil.getBoardFromFile("board.txt"));
        bd = new Board();
        AIPlayer p = new AIPlayer(Difficulty.MEDIUM, AIPlayer.BLACK);
        System.out.println(bd);
        System.out.println(p.getNextMove(bd));
    }
}
